In [1]:
from IPython.display import HTML

HTML('''<script>
code_show=true; 
function code_toggle() {
 if (code_show){
 $('div.input').hide();
 } else {
 $('div.input').show();
 }
 code_show = !code_show
} 
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>''')
Out[1]:

Hoe rijker hoe viezer

Dit notebook in Python is gemaakt naar aanleiding van het artikel met de naam "Hoe rijker hoe viezer" uit de Groene Amsterdammer op 19 december 2018: https://www.groene.nl/artikel/hoe-rijker-hoe-viezer

Tijdens het lezen van het stuk vielen mij een aantal zinnen op: "[..want er bestaat geen eenduidig causaal verband tussen de groei van de wereldbevolking en de ontwrichting van het klimaat,..]"

Het artikel zegt hiermee dat de landen met de grootste populaties niet zonder meer de grootste vervuilers zijn qua uitstoot van CO2.

en:

"[Over het algemeen lijkt eerder te gelden: hoe rijker, hoe viezer.]"

Hiermee wordt bedoeld dat er eerder een causaal verband lijkt te zijn met hoe goed een land het economisch doet (uitgedrukt in GDP per capita) en de uitstoot van CO2.

Deze twee uitgangspunten wil ik graag uitzoeken door een visualisatie te maken van een aantal gegevens. De gegevens haal ik van de world bank. Ik zoek daar de gegevens op van alle landen met hun GDP per capita, hun CO2 emissie in tonnen per capita en de bevolking van het land per jaar. De wereld bank heeft voor deze landen data vanaf 1960 tot aan 2014. Er is niet altijd alle data beschikbaar van alle landen per jaar waardoor er wat gaten in de data zitten. Dat los ik op door alleen de landen mee te nemen

Link naar de CO2 emissie publicatie: https://data.worldbank.org/indicator/EN.ATM.CO2E.PC

Link naar GDP per capita: https://data.worldbank.org/indicator/NY.GDP.PCAP.CD

Link naar populatie: https://data.worldbank.org/indicator/SP.POP.TOTL

In [2]:
# importeer libraries

import pandas as pd 
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline 
import plotly.graph_objs as go
import plotly.figure_factory as ff
from plotly import tools
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)

Inladen data en opschonen

In de csv bestanden van de data staat ook data over elke regio en andere groepsaggregaties die ik niet wil meenemen in mijn visualisatie en die haal er ik er uit.

In [3]:
# lijst van groeperingen die uit de data moeten worden gehaald

exclude = ["Central Europe and the Baltics",
           "Arab World",
           "Caribbean small states",
           "East Asia & Pacific (excluding high income)",
           "Early-demographic dividend",
            "East Asia & Pacific",
            "Europe & Central Asia (excluding high income)",
            "Europe & Central Asia",
            "European Union",
            "Fragile and conflict affected situations",
            "Heavily indebted poor countries (HIPC)",
            "IBRD only",
            "IDA & IBRD total",
            "IDA total",
            "IDA blend",
            "IDA only",
            "Not classified",
            "North America"
            "Latin America & Caribbean (excluding high income)",
            "Latin America & Caribbean",
            "Least developed countries: UN classification",
            "Low income",
            "High income",
            "Lower middle income",
            "Low & middle income",
            "Late-demographic dividend",
            "Middle income",
            "Middle East & North Africa (excluding high income)",
            "Middle East & North Africa",
            "OECD members",
            "South Asia",
            "Small states",
            "Euro area",
            "Other small states",
            "Sub-Saharan Africa",
            "Pre-demographic dividend",
            "Pacific island small states",
            "Post-demographic dividend",
            "Sub-Saharan Africa (excluding high income)",
            "East Asia & Pacific (IDA & IBRD countries)",
            "Europe & Central Asia (IDA & IBRD countries)",
            "Latin America & the Caribbean (IDA & IBRD countries)",
            "Middle East & North Africa (IDA & IBRD countries)",
            "South Asia (IDA & IBRD)",
            "Sub-Saharan Africa (IDA & IBRD countries)",
            "Upper middle income",
            "World"]
In [4]:
# Inlezen van de csv bestanden.
df_co2 = pd.read_csv('emissions.csv') #CO2
df_gdp = pd.read_csv('gdp.csv') # GDP
df_region = pd.read_csv('regions.csv') # hulp tabel voor regios
df_pop = pd.read_csv('pop.csv') # populatie
#df_co2.head()
In [5]:
# opschonen
for i in exclude:
    df_co2 = df_co2[df_co2['Country Name'] != i]
    df_gdp = df_gdp[df_gdp['Country Name'] != i]
In [6]:
df_co2 = df_co2.set_index(['Country Code'])
df_gdp = df_gdp.set_index(['Country Code'])
df_pop = df_pop.set_index(['Country Code'])
#df_gdp.head()

Samenvoegen van de data

De data is niet direct geschikt voor het maken van visualisaties. Ik doe daarom een paar berwerkingen op de data.

In [7]:
df_co2 = df_co2.merge(df_region, on='Country Code') # samenvoegen van regio en co2
In [8]:
# herschikken van de kolommen (regio naar voren halen)
region = df_co2['Region']
df_co2.drop(labels=['Region'], axis=1,inplace = True)
df_co2.insert(0, 'Region', region)
#df_co2.head()
In [9]:
# Melt van de data zodat year een kolom word
df_a = df_gdp.melt(id_vars = 'Country Name', var_name='year', value_name='gdp')
df_b = df_co2.melt(id_vars = 'Country Name', var_name='year', value_name='co2')
In [10]:
df_c = df_pop.melt(id_vars = 'country', var_name='year', value_name='pop')
In [11]:
dataset = pd.merge(df_a, df_b, on=['Country Name','year'])
dataset.rename(columns={'Country Name': 'country'}, inplace=True)
#dataset.head()
In [12]:
dataset = dataset.merge(df_c, on=['country','year'])
#dataset.head()
In [13]:
dataset = dataset.merge(df_region, how = 'left')
dataset.head()
Out[13]:
country year gdp co2 pop Country Code Region IncomeGroup
0 Aruba 1960 NaN NaN 54211.0 ABW Latin America & Caribbean High income
1 Afghanistan 1960 59.777327 0.0460599 8996351.0 AFG South Asia Low income
2 Angola 1960 NaN 0.0974716 5643182.0 AGO Sub-Saharan Africa Lower middle income
3 Albania 1960 NaN 1.25819 1608800.0 ALB Europe & Central Asia Upper middle income
4 Andorra 1960 NaN NaN 13411.0 AND Europe & Central Asia High income

GDP, populatie en CO2 uitstoot per land in 2007

De grootte van de bubbels geeft de populatie weer van de individuele landen. De kleur van landen geeft de regio in de wereld weer. De x-as staat voor de GDP per capita in Amerikaanse dollars en de y-as voor de uitstoot van CO2 in tonnen per capita.

In [14]:
# Subset van de data op basis van het jaar 2007
df_S = dataset.loc[dataset['year']=='2007']
In [15]:
import plotly.offline as off

#import pandas as pd

off.init_notebook_mode(connected=False)

#df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv")

colors = ['blue', 'orange', 'green', 'red', 'purple']

opt = []
opts = []
for i in range(0, len(colors)):
    opt = dict(
        target = dataset['Region'][[i]].unique(), value = dict(marker = dict(color = colors[i]))
    )
    opts.append(opt)

data = [dict(
  type = 'scatter',
  mode = 'markers',
  x = dataset['gdp'],
  y = dataset['co2'],
  text = dataset['country'],
  hoverinfo = 'text',
  opacity = 0.8,
  marker = dict(
      #size = 10, 
      size = dataset['pop'],
      sizemode = 'area',
      sizeref = 1000000
  ),
  transforms = [
      dict(
        type = 'filter',
        target = dataset['year'],
        orientation = '=',
        value = 2007
      ),
      dict(
        type = 'groupby',
        groups = dataset['Region'],
        styles = opts
    )]
)]
config = {
    'scrollZoom': True,
    'displayModeBar': True}

layout = dict(
    title='GDP and CO2 emission in 2007, bubble size is population',
    yaxis = dict(
       type = 'log',
       title = 'CO2 in tons per capita (log scale)'
        
    ),
    xaxis = dict(
        type = 'log',
        title = 'GDP in US$ per capita (log scale)')
)


off.iplot({'data': data, 'layout': layout}, validate=False, config=config)

Je zou clusters kunnen vormen rondom de landen uit de sub Sahara en de Europese landen samen met de VS en Australië.

Visualisatie van CO2 uitstoot op een wereldbol

In [16]:
def draw_map(dataset, title, colorscale, reversescale=False):
    trace = go.Choropleth(
                locations = dataset['country'],
                locationmode='country names',
                z = dataset['co2'],
                text = dataset['country'],
                autocolorscale =False,
                reversescale = reversescale,
                colorscale = colorscale,
                marker = dict(
                    line = dict(
                        color = 'rgb(0,0,0)',
                        width = 0.5)
                ),
                colorbar = dict(
                    title = 'CO2',
                    tickprefix = '')
            )

    data = [trace]
    layout = go.Layout(
        title = title,
        geo = dict(
            showframe = True,
            showlakes = False,
            showcoastlines = True,
            projection = dict(
                type = 'orthographic'
            )
        )
    )
    fig = dict( data=data, layout=layout )
    iplot(fig)
    
draw_map(df_S, 'CO2 emission/ capita per Country in 2007', "Reds")

Visualisatie van GDP op een wereldbol

In [17]:
def draw_map(dataset, title, colorscale, reversescale=False):
    trace = go.Choropleth(
                locations = dataset['country'],
                locationmode='country names',
                z = dataset['gdp'],
                text = dataset['country'],
                autocolorscale =False,
                reversescale = reversescale,
                colorscale = colorscale,
                marker = dict(
                    line = dict(
                        color = 'rgb(0,0,0)',
                        width = 0.5)
                ),
                colorbar = dict(
                    title = 'GDP',
                    tickprefix = '')
            )

    data = [trace]
    layout = go.Layout(
        title = title,
        geo = dict(
            showframe = True,
            showlakes = False,
            showcoastlines = True,
            projection = dict(
                type = 'orthographic'
            )
        )
    )
    fig = dict( data=data, layout=layout )
    iplot(fig)
    
draw_map(df_S, 'GDP per Country in 2007', "Blues", True)

Verdere bewerking op de data

Voor de volgende en laatste plot moet de data verder bewerkt worden zodat de data op alfabetische volgorde staat van land en jaartal. Niet funcionele data haal ik weg.

In [18]:
dataset.drop(['Country Code', 'IncomeGroup'], axis=1, inplace=True)
#dataset.head()
In [19]:
dataset = dataset.dropna()
In [20]:
dataset = dataset.sort_values(["country", 'year'])
In [21]:
# Alle jaartallen op een rijtje voor straks in de plot
years = sorted(dataset.year.unique().tolist())
In [22]:
dataset.columns = ['country', 'year', 'gdpPercap', 'co2', 'pop', 'continent']
dataset = dataset.astype({"pop": int})
dataset = dataset.reset_index(drop=True)
dataset.head()
Out[22]:
country year gdpPercap co2 pop continent
0 Afghanistan 1960 59.777327 0.0460599 8996351 South Asia
1 Afghanistan 1961 59.878153 0.0536043 9166764 South Asia
2 Afghanistan 1962 58.492874 0.0737648 9345868 South Asia
3 Afghanistan 1963 78.782758 0.0742327 9533954 South Asia
4 Afghanistan 1964 82.208444 0.0862925 9731361 South Asia
In [23]:
# Bewaar de dataset voor later
dataset.to_csv('dataset.csv', index=False)
In [24]:
from plotly.offline import init_notebook_mode, iplot
from IPython.display import display, HTML

import pandas as pd

init_notebook_mode(connected=True)

dataset = pd.read_csv('dataset.csv') # Dit is een hack, opnieuw laden anders doet-ie het niet
years = years 
# make list of continents
continents = []
for continent in dataset['continent']:
    if continent not in continents:
        continents.append(continent)
# make figure
figure = {
    'data': [],
    'layout': {},
    'frames': []
}

# fill in most of layout
figure['layout']['xaxis'] = {'title': 'CO2 emission (in metric tons) per capita (log scale)', 'type': 'log'}
figure['layout']['yaxis'] = {'title': 'GDP per Capita (log scale)', 'type': 'log'}
figure['layout']['hovermode'] = 'closest'
figure['layout']['sliders'] = {
    'args': [
        'transition', {
            'duration': 400,
            'easing': 'cubic-in-out'
        }
    ],
    'initialValue': '1952',
    'plotlycommand': 'animate',
    'values': years,
    'visible': True
}
figure['layout']['updatemenus'] = [
    {
        'buttons': [
            {
                'args': [None, {'frame': {'duration': 500, 'redraw': False},
                         'fromcurrent': True, 'transition': {'duration': 300, 'easing': 'quadratic-in-out'}}],
                'label': 'Play',
                'method': 'animate'
            },
            {
                'args': [[None], {'frame': {'duration': 0, 'redraw': False}, 'mode': 'immediate',
                'transition': {'duration': 0}}],
                'label': 'Pause',
                'method': 'animate'
            }
        ],
        'direction': 'left',
        'pad': {'r': 10, 't': 87},
        'showactive': False,
        'type': 'buttons',
        'x': 0.1,
        'xanchor': 'right',
        'y': 0,
        'yanchor': 'top'
    }
]

sliders_dict = {
    'active': 0,
    'yanchor': 'top',
    'xanchor': 'left',
    'currentvalue': {
        'font': {'size': 20},
        'prefix': 'Year:',
        'visible': True,
        'xanchor': 'right'
    },
    'transition': {'duration': 300, 'easing': 'cubic-in-out'},
    'pad': {'b': 10, 't': 50},
    'len': 0.9,
    'x': 0.1,
    'y': 0,
    'steps': []
}

# make data
year = 1952
for continent in continents:
    dataset_by_year = dataset[dataset['year'] == year]
    dataset_by_year_and_cont = dataset_by_year[dataset_by_year['continent'] == continent]

    data_dict = {
        'x': list(dataset_by_year_and_cont['co2']),
        'y': list(dataset_by_year_and_cont['gdpPercap']),
        'mode': 'markers',
        'text': list(dataset_by_year_and_cont['country']),
        'marker': {
            'sizemode': 'area',
            'sizeref': 100000,
            'size': list(dataset_by_year_and_cont['pop'])
        },
        'name': continent
    }
    figure['data'].append(data_dict)
    
# make frames
for year in years:
    frame = {'data': [], 'name': str(year)}
    for continent in continents:
        dataset_by_year = dataset[dataset['year'] == int(year)]
        dataset_by_year_and_cont = dataset_by_year[dataset_by_year['continent'] == continent]

        data_dict = {
            'x': list(dataset_by_year_and_cont['co2']),
            'y': list(dataset_by_year_and_cont['gdpPercap']),
            'mode': 'markers',
            'text': list(dataset_by_year_and_cont['country']),
            'marker': {
                'sizemode': 'area',
                'sizeref': 100000,
                'size': list(dataset_by_year_and_cont['pop'])
            },
            'name': continent
        }
        frame['data'].append(data_dict)

    figure['frames'].append(frame)
    slider_step = {'args': [
        [year],
        {'frame': {'duration': 300, 'redraw': False},
         'mode': 'immediate',
       'transition': {'duration': 300}}
     ],
     'label': year,
     'method': 'animate'}
    sliders_dict['steps'].append(slider_step)

    
figure['layout']['sliders'] = [sliders_dict]

iplot(figure)

Met de slider kun je de tijd aanpassen.

Conclusie

Over het algemeen zie alle drie de variabelen groeien: CO2 uitstoot per land wordt meer over tijd, GDP per land wordt meer over tijd en de populatie groeit over tijd.

Verder zie je tot halverwege de jaren '80, vooral de bubbels op de GDP-as groeien. Landen in Afrika onder de Sahara blijven vooral horizontaal zichzelf onderscheiden. Dat betekent dat de CO2 emissie wel veel variabiliteit laat zijn terwijl het GDP grotendeels vergelijkbaar blijft. Het tegenover gestelde zie je eigenlijk in Europa en Centraal Azie. Landen in Europa en Centraal Azie van voor de jaren '80 verschillen heel sterk van elkaar in zowel GDP als CO2 uitstoot. Vanaf de jaren 2000 zie je dat deze landen vooral qua GDP uit elkaar groeien. De bovenste bubbels zijn de Noord-Europese landen, die wel rijker worden maar niet meer CO2 gaan uitstoten terwijl landen zoals Rusland en Uzbekistan qua GDP achter blijven lopen.

Landen zoals India en China worden vooral heel groot qua populatie. Op het laatst (2014) ligt China op par met landen in Centraal Azie. India lijkt zich vooral te kunnen meten landen zoals Vietnam en Marokko rond het jaar 2014.

De uitspraak: Hoe rijker hoe viezer lijkt dus wel te kloppen: de laatste visualisatie laat zien dat de onderlinge verschillen tussen de landen consequent op GDP en CO2 met elkaar gecorreleerd zijn. Tijd is een factor die ervoor lijkt te zorgen dat GDP en CO2-uitstoot toeneemt: We worden dus met z'n allen steeds rijker en viezer.

Nog een laatste opmerking: de enige grote uitzondering in dit verhaal is de VS. De VS is heeft altijd een hoog GDP en CO2-uitstoot gehad vanaf de jaren '60 tot aan 2014.